
#include <time.h>
#include "list.h"
#include "metaSet.h"
#include "json.h"


DEF_LIST_FUNCTIONS(jsonPara, uint32, uint32);

/* make the meter data of the type member, use the offset feature of member from type value. */
typedef struct 
{
	char** cq_cmds;
	int count;
} cq_list_t;

typedef struct EventType
{
	int eventCode;
	int subEvent;
} EventType;

/////////////////// static values //////////////////////

//static char str[MAX_NUM] = {0};
//char str[MAX_NUM] = {0};


/////////////////// static functions //////////////////////
//static int verifyRequest(); // verify the QCS Request and QCS id.


// insert the data to the ParameterList.
static int insertPrarmeterList(jsonPara_list * list, char* name, stbDataType type, char* value)
{
	list_node_jsonPara * node = malloc(sizeof(list_node_jsonPara));
	if (node == NULL)
		return -1;
	memset(node, 0x00, sizeof(list_node_jsonPara));
	strncpy(node->data.name, name, 29);
	node->data.type = type;
	if (type == STB_DATA_BEAN || type == STB_DATA_BEAN_END)
	{
	}
	else if (type == STB_DATA_LIST|| type == STB_DATA_LIST_END)
	{
	}
	else
	{
		strncpy(node->data.value, value, strlen(value)>MAX_STR_LEN-1?MAX_STR_LEN-1:strlen(value));
	}

	//printf("Type:%d, Name:%s, Value:%s\n",node->data.type,node->data.name,node->data.value);
	
	insert_into_jsonPara_list_tail(node, list);// add the trituple node to the list
	return 0;
}

/* convert the struct data to the list or string
 * list or str - the list or string convert to 
 * meta - the meta of struct
 * data - the struct data 
 */
static void valueConvert(jsonStruct* message, META* meta, void* data)
{
	int count = 0;
	char strValue[MAX_STR_LEN] = {0};
	char* name = meta->alias;
	if (!name)
		name = meta->name; // use the alias prior.
	char* p = (char*)data+meta->offset;

	 //printf("the offset of %s is: %d(%s)\n", meta->name, meta->offset, p);
	if (meta->type == STB_DATA_BEAN)
		encapsulateJsonList(message, name, p, meta->child, meta->type);
	
	else if(meta->type == STB_DATA_LIST)
	{
		encapsulateJsonList(message, name, p, meta->child, meta->type);
	}	
	else if(meta->type == STB_DATA_BEAN_NULL)
	{
		encapsulateJsonList(message, name, p, meta->child, meta->type);
	}
	else if(meta->type == STB_DATA_NULL)
	{
		//do nothing
	}
	else
	{
		switch (meta->type)
		{
			case STB_DATA_UINT64:
				snprintf(strValue, MAX_STR_LEN, "%llu", *(uint64*)(p));
				break;
			case STB_DATA_UINT32:
				snprintf(strValue, MAX_STR_LEN, "%u", *(uint32*)(p));
				break;
			case STB_DATA_UINT16:
				snprintf(strValue, MAX_STR_LEN,"%u", *(uint16*)(p));
				break;
			case STB_DATA_UINT8:
				snprintf(strValue, MAX_STR_LEN,"%u", *(uint8*)(p));
				break;
			case STB_DATA_TIMEVAL:
				{
					struct tm *tm_ptr = localtime((time_t *)(p));
					strftime(strValue, 27,"%Y-%m-%d %H:%M:%S",tm_ptr);
					break;
				}
			case STB_DATA_UINT8_ARRAY:
				{
					count = (int)meta->alias;
					
					int j = 0;
					for (j = 0; j<count; j++)
					{
						int len = strlen(strValue);
						
						if (j == count-1)
							snprintf(strValue+len, MAX_STR_LEN-len,"%d", *(uint8*)(p + j));
						else
							snprintf(strValue+len, MAX_STR_LEN-len,"%d,", *(uint8*)(p + j));
							
						/*
						if (j == 0)
							snprintf(strValue+len, MAX_STR_LEN-len,"[%d", *(uint8*)(p + j));
						else if(j == count-1)
							snprintf(strValue+len, MAX_STR_LEN-len,"%d]", *(uint8*)(p + j));
						else
							snprintf(strValue+len, MAX_STR_LEN-len,"%d,", *(uint8*)(p + j));
							*/
					}
				}
				break;
			case STB_DATA_UINT32_ARRAY:
				{
					count = (int)meta->child;
					
					int j = 0;
					for (j = 0; j<count; j++)
					{
						int len = strlen(strValue);
						
						if (j == count-1)
							snprintf(strValue+len, MAX_STR_LEN-len,"%d", *((uint32*)(p) + j));
						else
							snprintf(strValue+len, MAX_STR_LEN-len,"%d,", *((uint32*)(p) + j));
							
						/*
						if (j == 0)
							snprintf(strValue+len, MAX_STR_LEN-len,"[%d", *(uint8*)(p + j));
						else if(j == count-1)
							snprintf(strValue+len, MAX_STR_LEN-len,"%d]", *(uint8*)(p + j));
						else
							snprintf(strValue+len, MAX_STR_LEN-len,"%d,", *(uint8*)(p + j));
							*/
					}
				}
				break;
			case STB_DATA_IPADDR:
				{
					unsigned char* pIp = (unsigned char*)p;	//network seq
					snprintf(strValue, MAX_STR_LEN, "%d.%d.%d.%d", *(pIp), *(pIp+1), *(pIp+2), *(pIp+3));
				}
				break;
				
			case STB_DATA_STR:
					snprintf(strValue, MAX_STR_LEN,"%s", (char*)(p));
					//printf("strValue=%s\n", strValue);
					break;
			case STB_DATA_STR_PTR:
				snprintf(strValue, MAX_STR_LEN,"%s", (char*)(*(int*)(p)));
				break;
			case STB_DATA_FLOAT:
				snprintf(strValue, MAX_STR_LEN, "%f", *(float*)(p));
				break;
			case STB_DATA_ENUM:
				snprintf(strValue, MAX_STR_LEN, "%d", *(int*)(p));
				break;
			case STB_DATA_BOOL:
				if (*(int*)(p))
					snprintf(strValue, MAX_STR_LEN, "%s", "TRUE");
				else
					snprintf(strValue, MAX_STR_LEN, "%s", "FALSE");
					
				break;
			case JSON_DATA_LIST:
				{
					listHead* pHead = (listHead*)p;
					listNode* pNode = firstNode(pHead);
					printf("pHead:%08X pNode:%08X \n", p, pNode);
					insertPrarmeterList(&(message->list), name, STB_DATA_LIST, NULL);
					while (pNode != NULL )
					{
						char* pData = (char*)pNode + sizeof(listNode) + sizeof(uint32); /* sizeof KEY */
						
						printf("pNode:%08X, pData:%08X child:%08X \n", pNode, pData, meta->child);
						encapsulateJsonList(message, "", pData, meta->child, STB_DATA_BEAN);

						pNode = nextListNode(pNode);
					}
					
					insertPrarmeterList(&(message->list), "", STB_DATA_LIST_END, NULL);
					return;
			}
			case JSON_DATA_PTR:
					//printf("pNode:%08X, pData:%08X child:%08X \n", pNode, pData, meta->child);
					encapsulateJsonList(message, name, *((uint32*)p), meta->child, STB_DATA_BEAN);
					return;
			default:
				printf("meta->type: %u\n", meta->type);
				strcpy(strValue, "Not support value type");
				break;
		}
		insertPrarmeterList(&(message->list), name, meta->type, strValue);
	}
}



////////////////////// json parse ///////////////////////////////////////
// parse the buf in json case
static int parse(char* buf, json_parse_result_t* rp)
{
	cq_list_t* pcql = NULL;
	int ret = 0;
	char *p = NULL;
	char *pr0,*pr1,*pr2,*pr3;

	if ((ret = strstr(buf, "\"parameterList\":[\""))>0)
	{
		rp->type = RT_GETPARAM;
		printf("ret: %d \n", ret);
		p = buf + ret + strlen("\"parameterList\":[\"") -1;
	}
	else if ((ret = strstr(buf, "configParameterList\":{\""))>0)
	{
		rp->type = RT_CONFIG;
		p = buf + ret + strlen("configParameterList\":{\"") -1;
	}
	else 
	{
		printf("qcs parse return -1 ***************\n");
		return -1; // not find or verify any type of qcs request .
	}

	int len = 1; 
	pr0 = p;
	pr2 = strchr(p, '}');
	while (1) // get the counts of the commands
	{
		pr1 = strchr(pr0, ',');
		if (pr1 == NULL || pr1 > pr2)
		{
			break;
		}
		len++;
		pr0 = pr1+1;
	}
	printf("get %d nodes in command. type: %d\n", len, rp->type);

	pcql = malloc(sizeof(cq_list_t));
	if (pcql == NULL)
		return -2;
	
	pcql->count = len;
	pcql->cq_cmds = malloc(len * sizeof(char*));
	
	if (pcql->cq_cmds == NULL)
	{
		return -2;  // no memory exception.
	}
	memset(pcql->cq_cmds, 0, len * sizeof(char*));
	// ret = ParseGetParameterValues(buf, pcql->cq_cmd);

	// fetch the cmds from the buf
	pr0 = p;

	int i = 0;
	pr2 = strchr(p, '}');  // end of the bean
	for (; i<len; i++)
	{
		pr1 = strchr(pr0, ',');
		if (pr1 == NULL || pr1 >pr2)
		{
			pr1 = pr2;
		}
		while (*pr0 != '"') // scape the characters before "
			pr0++;
		pr3 = pr1;
		while (*pr3 != '"')	// scape the characters after "
			pr3--;
		
		int sublen = pr3 - pr0 - 1;
// 		printf("sublen : %d \n", sublen);

		pcql->cq_cmds[i] = malloc(sublen+1);
		if (pcql->cq_cmds[i] == NULL) // if malloc failed
		{
			// free the cmds has malloced .
			int j = 0;
			for (; j<i; j++)
			{
				free(pcql->cq_cmds[j]);
				pcql->cq_cmds[j] = NULL;
			}
			free(pcql->cq_cmds);
			pcql->cq_cmds = NULL;
			free(pcql);
			return -2; // malloc error 
		}
		strncpy(pcql->cq_cmds[i], pr0+1, sublen);
		pcql->cq_cmds[i][sublen] = '\0';

// 		printf("cq cmd : %s \n", pcql->cq_cmd[i]);

		pr0 = pr1+1; // 
	}
	rp->data = pcql;
	return 0;
}

/*
 * parse String like "eventType":{"eventCode":"5", "subEvent":51}
 */
static int parseEvent(char* buf, EventType *eventType)
{
	int ret = 0;
	char *p = NULL;
	char *pTmp1, *pTmp2;
	if ((ret = strstr(buf, "\"eventType\":{\""))>0)
	{
		p = buf + ret + strlen("\"eventType\":{\"") -1;
	}
	else 
	{
		printf("qcs parseEvent return -1 ***************\n");
		return -1; // not find "eventType"
	}

	pTmp1 = strchr(p, '}');// end of "eventType"
	if(!pTmp1)
		return -1; //not find '}' end of "eventType"

	pTmp2 = strchr(p, ',');
	if (!pTmp2 || pTmp2 > pTmp1)
		return -1; //format error

	char *tmpEventStr = (char *)malloc(pTmp1-p+1);
	if(!tmpEventStr)
		return -2;
	memset(tmpEventStr, 0X00, pTmp1-p+1);
	memcpy(tmpEventStr, p, pTmp1-p);
	
	sscanf(tmpEventStr, "\"eventCode\":%d, \"subEvent\":%d", &(eventType->eventCode), &(eventType->subEvent));
	printf("parseEvent(): tmpEventStr=[%s], eventCode=%d, subEvent=%d\n", 
		tmpEventStr, eventType->eventCode, eventType->subEvent);

	free(tmpEventStr);// free memory

	return 0;
}

static int parseEventStr(char* buf, EventType *eventType)
{
	int ret = 0;
	char *p = NULL;
	char *pTmp1, *pTmp2;
	if ((ret = strstr(buf, "\"eventType\":{\""))>0)
	{
		p = buf + ret + strlen("\"eventType\":{\"") -1;
	}
	else 
	{
		printf("qcs parseEvent return -1 ***************\n");
		return -1; // not find "eventType"
	}

	pTmp1 = strchr(p, '}');// end of "eventType"
	if(!pTmp1)
		return -1; //not find '}' end of "eventType"

	pTmp2 = strchr(p, ',');
	if (!pTmp2 || pTmp2 > pTmp1)
		return -1; //format error

	char *tmpEventStr = (char *)malloc(pTmp1-p+1);
	if(!tmpEventStr)
		return -2;
	memset(tmpEventStr, 0X00, pTmp1-p+1);
	memcpy(tmpEventStr, p, pTmp1-p);
	
	sscanf(tmpEventStr, "\"eventCode\":\"%d\", \"subEvent\":\"%d\"", &(eventType->eventCode), &(eventType->subEvent));
	printf("parseEventStr(): tmpEventStr=[%s], eventCode=%d, subEvent=%d\n", 
		tmpEventStr, eventType->eventCode, eventType->subEvent);

	free(tmpEventStr);// free memory

	return 0;
}



// parse the valuestr in json case
// s - the string be parsed
// name - the parsed string of name
// value - the parsed string of value
static int valuestr(char *s, char *name, char *value)
{
	char *pr0,*pr1;
	int n;

	if (s == NULL || name == NULL || value == NULL)
		return -1;

	pr0=(char*)s;
	pr1=strchr(pr0,':');
	if (!pr1) // not find the ':' character.
	{
		return -1;
	}

	n = pr1 - pr0;

	strncpy(name, pr0, n-1);
	name[n-1]='\0';

	n = strlen(s) - n - 1;
	strncpy(value, pr1 + 2, n);  // escape the :" 
	value[n]='\0';

	// printf("value str: %s , %s\n", name, value);;
	return 0;
}


int  initJsonPara(jsonStruct* message)
{
	if(message == NULL)
	{
		return -1;
	}

	message->buf = (char*) malloc(INIT_BUF_SIZE);
	message->buf_size = INIT_BUF_SIZE;
	
	message->opt = 0;
	uint32 maxListCount = MAX_LIST_COUNT;
	init_jsonPara_list(&(message->list));
	set_config_jsonPara_list(&(message->list), &maxListCount);
	
	return 0;
}

/***************************interface function**************************/
int 
setRequestType(jsonStruct* message, operator_e opt)
{
	if(message == NULL || opt < OP_RESP ||opt > OP_HTTPCLIENT_RCV)
	{
		return 1;
	}

	message->opt = opt;

	return 0;
}

#define BUF_SIZE MAX_STR_LEN*2
// format the list to string in json 
int  format(jsonStruct *message)
{
	char temp[BUF_SIZE] = "";
	if (message== NULL)
		return -1;

	message->buf = (char*) malloc(INIT_BUF_SIZE);
	memset(message->buf, 0x00, INIT_BUF_SIZE);
	message->buf_size = INIT_BUF_SIZE;
	// cts_strcpy((message->buf),"{");

	list_node_jsonPara * node = get_first_jsonPara_node(&(message->list));
	while(node)
	{	
		if (node->data.type == STB_DATA_BEAN)  // BEAN
		{
			if (strlen(node->data.name)) 
			{ // have the name
				strcat(temp,"\"");
				strcat(temp,node->data.name);
				strcat(temp,"\":");
			}
			strcat(temp,"{");			
		}
		else if (node->data.type == STB_DATA_BEAN_END)  // BEAN end
		{
			if(message->buf[strlen(message->buf)-1] ==',')
				message->buf[strlen(message->buf)-1] = '\0';
			strcat(temp,"}");
			strcat(temp,",");		
		}
		else if(node->data.type == STB_DATA_LIST)
		{
			if (strlen(node->data.name)) 
			{ // have the name
				strcat(temp,"\"");
				strcat(temp,node->data.name);
				strcat(temp,"\":");
			}
			strcat(temp,"[");		
		}
		else if(node->data.type == STB_DATA_LIST_END)
		{
			if(message->buf[strlen(message->buf)-1] ==',')	//if multiset is null,should not delete '['
				message->buf[strlen(message->buf)-1] = '\0';
			strcat(temp,"]");
			strcat(temp,",");		
		}
		else
		{
			strcat(temp,"\"");
			strcat(temp,node->data.name);
			strcat(temp,"\":\"");
			strcat(temp,node->data.value);
			strcat(temp,"\"");
			strcat(temp,",");
		}

		int tempLen = strlen(temp);
		int strLen = strlen(message->buf);
		if (tempLen + strLen >= message->buf_size -1)
			{
			char* p = message->buf;
			message->buf_size *= 2;
			message->buf = (char*) malloc(message->buf_size);
			memcpy(message->buf, p, strLen+1);
			free(p);
			}

		memcpy(message->buf+strLen, temp, tempLen);
		memset(temp, 0, BUF_SIZE);

		node= get_next_jsonPara_node(node);  // next node
	}
	
	message->buf[strlen(message->buf)-1] = '\0';
	//strcat((message->buf),"}");

	//printf("message->buf:%s\n", message->buf);

	release_jsonPara_list(&(message->list));

	return 0;
}


char* 
getJsonEncapsulateStr(jsonStruct* message)
{
	if(message == NULL)
	{
		return NULL;
	}

	//cts_strncpy(str, message->buf, INIT_BUF_SIZE);
	return message->buf;
}

int freeJson(jsonStruct *message)
{
	if(message == NULL)
		return -1;
	if(message->buf == NULL)
		return -1;
	free(message->buf);
	message->buf = NULL;
	message->buf_size = 0;
	return 0;
}

#if 0
/*
 * parse the request string from the qcs
 * message - the request string struct
 * data - string buffer
 * length - the length of data string
 */
parseRet  
qcsRequestParse(operator_e opt, char *data, int length)
{
	json_parse_result_t   jpr = {0};
	parseRet ret = PR_SUCCESS;

	if(data == NULL)
	{
		return PR_PARA_NULL;
	}

	if(length > INIT_BUF_SIZE)
	{
		return PR_STR_OVERFLOW;
	}

	//cts_strncpy(message->buf, data, length);		//save request string to the buffer of json structure
	
	switch (opt)
	{
	/*	
	case OP_HTTPCLIENT_SENDRESP:
		{
			if (operinfo->opret == OR_SUCCESS)
				;
			else if (operinfo->opret == OR_FAILED)
				printf("");
			else 
				;
		}
		break;
		*/
	case OP_HTTPCLIENT_RCV:
	case OP_POLL:
		{
			// first parse "eventType":{"eventCode":5, "eventCode":51}
			EventType et = {0};
			if(parseEvent(data, &et) == 0)
			{
				printf("parseEvent Success! eventCode=%d, eventCode=%d\n", et.eventCode, et.subEvent);
			}
					
			ret = parse(data, &jpr);
			if (ret)
			{
				return ret; // parse failed 
			}
			
			if (jpr.type == RT_CONFIG) // when the buf is CONFIG command. parse the values and set the configs to the config module.
			{
				//check eventType
				if(et.eventCode == EVENT_NETWORK_TEST)
				{
					if (!isDoingAlarmNetTest && (1 == isNetTestFinish))
						clearNetworkTestParas();
				}
				
				int i = 0;
				cq_list_t* cql = jpr.data;
				printf("cql->count = %d\n", cql->count);
				while (i < cql->count)
				{
					char parameter[30];	//bug fix 24->30 .weiyc
					char value[256];
					printf("(%d) (%s) - ", i, cql->cq_cmds[i]);	
					if (valuestr(cql->cq_cmds[i], parameter, value))
					{
						ret = PR_FORMAT_ERROR; // the string is not in spec format
						break;
					}
					
					config(parameter, value); // call config module.
					i++;
				}

				//check eventType
				if(et.eventCode == EVENT_NETWORK_TEST
					&& ret == PR_SUCCESS)
				{
					if (!isDoingAlarmNetTest && (1 == isNetTestFinish))
						runNetworkTestByEvent(et.subEvent);
				}
				
			}
			else if (jpr.type == RT_GETPARAM)
			{
#if 0			
				int i = 0;
				cq_list_t* cql = jpr.data;
				printf("cql->count = %d\n", cql->count);
				while (i < cql->count)
				{
					printf("RT_GETPARAM i = %d\n", i);
					META* meta  = NULL;
					meta = getMetabyReqName(cql->cq_cmds[i]);
					if(meta == NULL)
					{
						printf("parameter query don't support!\n");
						ret = PR_NOT_SUPPORT;
						break;
					}
					meta->type = STB_DATA_BEAN;
					i++;
				}
				if(ret == PR_SUCCESS)
				{
					fn_creat_connRequestMsg((void *)&httpClientPara_connReq,NULL);	
				}
#endif				
			}
			else
			{
				ret = PR_COM_UNKNOW; // not config or getparameter command
			}
			printf("\n");
			break;
		}
	default:
		ret = PR_INVALID_OPT; // not avaliable operator. 
		break;
	}
	
	if (jpr.data)
	{
		// clear the jpr.data which is malloced by parse.
		cq_list_t* cql = jpr.data;
		int i = 0;
		for(;i < cql->count;i++)
		{
			free(cql->cq_cmds[i]); // free each cmd in cmds
			cql->cq_cmds[i] = NULL;
		}
		free(cql->cq_cmds); // free cmds
		free(cql);
		jpr.data = NULL; // clear the data

		printf("after clear!\n");
	}
	 printf("qcsRequestParse ret =%d\n", ret);
	return ret;
}

parseRet  
alarmQcsRequestParse(char *data, int length)
{
	json_parse_result_t   jpr = {0};
	parseRet ret = PR_SUCCESS;
	char *p = NULL;
	char *pTmp1, *pTmp2;
	int isIncludeOperate = -1;

	//char *test  = "{\"result\":0, \"includeOperate\":1, \"events\":[{\"eventType\":{\"eventCode\":3,\"subEvent\":51}, \"deviceId\":{\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"deviceid\":\"00:25:90:01:af:7e\"},\"configParameterList\":{\"dest\":\"www.163.com\",\"protocolType\":\"1\",\"pingCount\":\"8\"}},{\"eventType\":{\"eventCode\":3,\"subEvent\":52},\"deviceId\":{\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"deviceid\":\"00:25:90:01:af:7e\"},\"configParameterList\":{\"dest\":\"172.16.34.141\",\"port\":\"5001\"}},{\"eventType\":{\"eventCode\":5,\"subEvent\":55},\"deviceId\":{\"deviceid\":\"00:25:90:01:af:7e\",\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"platform\":null},\"configParameterList\":{\"dest\":\"112.4.17.39\",\"protocolType\":\"1\",\"pingCount\":\"3\",\"port\":\"\",\"devName\":\"\",\"packetSize\":\"\",\"ttl\":\"64\",\"interval\":\"\",\"testTime\":\"5\"}}]}";

//char *test = "{\"result\":0,\"includeOperate\":1,\"events\":null}";
//char *test = "{\"result\":0, \"includeOperate\":1, \"events\":[{\"eventType\":{\"eventCode\":3,\"subEvent\":51},\"deviceId\":{\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"deviceid\":\"00:25:90:01:af:7e\"},\"configParameterList\":{\"dest\":\"www.163.com\",\"protocolType\":\"1\",\"pingCount\":\"8\"}},{\"eventType\":{\"eventCode\":3,\"subEvent\":52},\"deviceId\":{\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"deviceid\":\"00:25:90:01:af:7e\"},\"configParameterList\":{\"dest\":\"172.16.34.141\",\"port\":\"5001\"}},{\"eventType\":{\"eventCode\":5,\"subEvent\":55},\"deviceId\":{\"deviceid\":\"00:25:90:01:af:7e\",\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"platform\":null},\"configParameterList\":{\"dest\":\"www.163.com\",\"protocolType\":\"1\",\"pingCount\":\"3\",\"port\":\"\",\"devName\":\"\",\"packetSize\":\"\",\"ttl\":\"22\",\"interval\":\"\",\"testTime\":\"5\"}},{\"eventType\":{\"eventCode\":3,\"subEvent\":51},\"deviceId\":{\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"deviceid\":\"00:25:90:01:af:7e\"},\"configParameterList\":{\"dest\":\"www.baidu.com\",\"protocolType\":\"1\",\"pingCount\":\"7\"}},{\"eventType\":{\"eventCode\":3,\"subEvent\":52},\"deviceId\":{\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"deviceid\":\"00:25:90:01:af:7e\"},\"configParameterList\":{\"dest\":\"172.16.34.141\",\"port\":\"5001\"}},{\"eventType\":{\"eventCode\":3,\"subEvent\":51},\"deviceId\":{\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"deviceid\":\"00:25:90:01:af:7e\"},\"configParameterList\":{\"dest\":\"www.126.com\",\"protocolType\":\"1\",\"pingCount\":\"2\"}},{\"eventType\":{\"eventCode\":5,\"subEvent\":55},\"deviceId\":{\"deviceid\":\"00:25:90:01:af:7e\",\"mac1\":\"0\",\"mac2\":\"00:25:90:01:af:7e\",\"platform\":null},\"configParameterList\":{\"dest\":\"112.4.17.39\",\"protocolType\":\"1\",\"pingCount\":\"3\",\"port\":\"\",\"devName\":\"\",\"packetSize\":\"\",\"ttl\":\"125\",\"interval\":\"\",\"testTime\":\"5\"}}]}";

	//data = test;

	do
	{
		if(data == NULL)
		{
			ret = PR_PARA_NULL;
			break;
		}

		if(length > INIT_BUF_SIZE)
		{
			ret = PR_STR_OVERFLOW;
			break;
		}

		char *end = data + strlen(data) -1;

		if ((ret = kmp(data, "\"includeOperate\":")) >= 0)
		{
			p = data + ret + strlen("\"includeOperate\":");
			pTmp1 = data + ret;

			pTmp2 = strchr(pTmp1, ',');
			if (!pTmp2)
			{
				ret = -1;
				break;
			}
			
			char *tmpStr = (char *)malloc(pTmp2 -pTmp1 + 1);

			if(!tmpStr)
			{
				ret = -2;
				break;
			}

			memset(tmpStr, 0X00, pTmp2 -pTmp1 + 1);
			cts_memcpy(tmpStr, pTmp1, pTmp2 - pTmp1);

			sscanf(tmpStr, "\"includeOperate\":%d", &isIncludeOperate);

			free(tmpStr);

			printf("alarmQcsRequestParse(): isIncludeOperate=%d\n", isIncludeOperate);

			if (isIncludeOperate != 1)
			{
				ret = -1;
				break;
			}

#if 1
			int n = kmp(data, "\"events\":[");
			int i, left = 0, right = 0;
			int flag = 0;
			
			if (n >= 0)
			{
				p = data + n + strlen("\"events\":[");

				int done = 0;
				
				while(!done)
				{
					for (i = 0; i< (end - p); i++)
					{
						if ('{' == p[i])
						{
							left++;
						}
						else if ('}' == p[i])
						{
							right++;
						}

						if (left && (left == right))
						{
							flag = 1;
							break;
						}
					}

					printf("++++p=%s\n", p);

					if (1 == flag)
					{
						left = 0;
						right = 0;
					
						EventType et = {0};
						if(parseEvent(p, &et) == 0)
						{
							printf("parseEventStr Success! eventCode=%d, eventCode=%d\n", et.eventCode, et.subEvent);

							ret = parse(p, &jpr);
							printf("11111 jpr.type=%d\n", jpr.type);
							
							if (ret)
							{
								printf("parse, ret = %d\n", ret);
								break;
							}
							else
							{
								if (jpr.type == RT_CONFIG) // when the buf is CONFIG command. parse the values and set the configs to the config module.
								{
									//check eventType
									if(et.eventCode == EVENT_NETWORK_TEST)
									{
										//clearNetworkTestParas();
									}
									
									int i = 0;
									cq_list_t* cql = jpr.data;
									printf("cql->count = %d\n", cql->count);
									while (i < cql->count)
									{
										char parameter[30];	//bug fix 24->30 .weiyc
										char value[256];
										printf("(%d) (%s) - ", i, cql->cq_cmds[i]);	
										if (valuestr(cql->cq_cmds[i], parameter, value))
										{
											ret = PR_FORMAT_ERROR; // the string is not in spec format
											break;
										}
										
										fillNetTestData(et.subEvent, parameter, value); // call config module.
										i++;
									}

									adjustNetParaCount(et.subEvent);

								}
							}
						}

						p += i;
						p += 1;

						printf("++++i=%d\n", i);

						if ((p == end) || (-1 == kmp(p, "{")))
						{
							done = 1;
						}
					}
					else
					{
						done = 1;
					}
				};
			}
#endif		
		}
	}while(0);

	printf("alarmQcsRequestParse ret =%d\n", isIncludeOperate);

	if (1 == isIncludeOperate)
	{
		showNetPara();
		handleAlarmNetTest();
	}

	return ret;
}
#endif

/*
 * encapsulate the parameters in a struct to the list or strings.
 * message - the destinations for the encapsulate struct.
 * name - the name string of the type 
 * data - the point to the struct, which will be encased.
 * meta - the point to the meta data of struct 
 */
encapsulateRet 
encapsulateJsonList(jsonStruct* message, char* name, void* data, META* meta, uint16 type)
{
	int i= 0;
	encapsulateRet ret = ER_SUCCESS;
	printf(">>>>>>>>>>>...encapsulateJsonList name:%s, data:%08X, type:%u \n", name, data, type);
	do
	{
		if(message == NULL)
		{
			ret = ER_PARA_NULL;
			break;
		}
		printf("encapsulateJsonList before insertPrarmeterList  %d\n", meta->type);
		if(type == STB_DATA_BEAN)
			insertPrarmeterList(&(message->list), name, STB_DATA_BEAN, NULL);
		
		if(type == STB_DATA_LIST)
			insertPrarmeterList(&(message->list), name, STB_DATA_LIST, NULL);
		
		if(type == STB_DATA_BEAN_NULL)
		{
			insertPrarmeterList(&(message->list), name, STB_DATA_BEAN, NULL);
			insertPrarmeterList(&(message->list), name, STB_DATA_BEAN_END, NULL);
			break;
		}
		if (data == NULL || meta == NULL)
		{
			//printf("Error\n");
			insertPrarmeterList(&(message->list), "error", STB_DATA_STR, "Not supported!");
			insertPrarmeterList(&(message->list), "", STB_DATA_BEAN_END, NULL);
			ret = ER_NOT_SUPPORT;
			break;
		}

		while (1)
		{
			printf("meta[%d].name :%s\n", i, meta[i].name);
			if (!meta[i].name)
			{
				break;
			}
			valueConvert(message, meta+i, data);
			i++;
			printf("i = %d\n", i);
		}
		if(type == STB_DATA_BEAN)
			insertPrarmeterList(&(message->list), name, STB_DATA_BEAN_END, NULL);
		if(type == STB_DATA_LIST)
			insertPrarmeterList(&(message->list), name, STB_DATA_LIST_END, NULL);

	}while(0);


	//ADD TEST
	#if 1
		printf("------------show list(begin)-------------\n");
		list_node_jsonPara * node = get_first_jsonPara_node(&(message->list));
		while(node)
		{
				printf("  type(%d)---",node->data.type);
				printf("name(%s)---",node->data.name);
				printf("value(%s)++++++++",node->data.value);
				printf("len(%d)++++++++\n",strlen(node->data.value));
				node= get_next_jsonPara_node(node);  // next node
		}
		printf("------------show list(end)--------------\n");
	#endif

	
	return ret;	
}

